package com.ins1st.config.shiro;

import cn.hutool.crypto.SecureUtil;
import com.ins1st.api.SysLoginLogApi;
import com.ins1st.api.SysMenuApi;
import com.ins1st.api.SysUserApi;
import com.ins1st.base.R;
import com.ins1st.entity.SysLoginLog;
import com.ins1st.entity.SysMenu;
import com.ins1st.entity.SysUser;
import com.ins1st.exception.AuthException;
import com.ins1st.http.HttpContext;
import com.ins1st.util.ShiroUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @program: ins1st-cloud
 * @description:
 * @author: coderSun
 * @create: 2019-11-19 09:57
 **/
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private SysUserApi sysUserApi;
    @Autowired
    private SysMenuApi sysMenuApi;
    @Autowired
    private SysLoginLogApi sysLoginLogApi;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Set<String> set = new HashSet<>();
        R<List<SysMenu>> r = this.sysMenuApi.queryMenusByUserId(ShiroUtil.getUser().getId());
        for (SysMenu sysMenu : r.getData()) {
            if (StringUtils.isNotBlank(sysMenu.getRole()) && !sysMenu.getRole().contains("#")) {
                String[] roles = sysMenu.getRole().split(",");
                for (int i = 0; i < roles.length; i++) {
                    set.add(roles[i]);
                }
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(set);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String userName = token.getUsername();
        String userPassword = String.valueOf(token.getPassword());
        String tenantId = token.getHost();
        if (StringUtils.isBlank(userName)) {
            saveLog(userName, "2", "用户名不能为空");
            throw new AuthenticationException("用户名不能为空");
        }
        if (StringUtils.isBlank(userPassword)) {
            saveLog(userName, "2", "密码不能为空");
            throw new AuthenticationException("密码不能为空");
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserName(userName);
        sysUser = this.sysUserApi.selectOne(sysUser).getData();
        if (sysUser == null) {
            saveLog(userName, "2", "用户不存在");
            throw new AuthenticationException("用户不存在");
        }
        if (!SecureUtil.md5(userName + "-" + userPassword).equals(sysUser.getUserPassword())) {
            saveLog(userName, "2", "密码错误");
            throw new AuthenticationException("密码错误");
        }
        if (sysUser.getLoginStatus().equals("1")) {
            saveLog(userName, "2", "用户被锁定,联系管理员");
            throw new AuthenticationException("用户被锁定,联系管理员");
        }
        R<List<SysMenu>> r = this.sysMenuApi.queryMenusByUserId(sysUser.getId());
        if (r.getData() == null || r.getData().size() == 0) {
            saveLog(userName, "2", "该账号无角色权限");
            throw new AuthenticationException("该账号无角色权限");
        }
        saveLog(userName, "1", "登入成功");
        sysUser.setTenantId(tenantId);
        return new SimpleAuthenticationInfo(sysUser, userPassword, getName());
    }

    private void saveLog(String userName, String success, String result) {
        SysLoginLog log = new SysLoginLog();
        log.setLoginName(userName);
        log.setLoginIp(HttpContext.getIp());
        log.setLoginSuccess(success);
        log.setLoginResult(result);
        log.setLoginTime(new Date());
        this.sysLoginLogApi.insert(log);
    }
}
